package com.fishingwithme.infrastructure;

import com.fishingwithme.domain.spots.SpotType;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@MappedTypes(List.class)  // 处理的 Java 类型
@MappedJdbcTypes(JdbcType.VARCHAR)  // 对应的 JDBC 类型
public class SpotTypeListTypeHandler extends BaseTypeHandler<List<SpotType>> {
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final TypeReference<List<SpotType>> TYPE_REF =
            new TypeReference<>() {
            };

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
                                    List<SpotType> parameter, JdbcType jdbcType) throws SQLException {
        try {
            List<String> types = parameter.stream().map(SpotType::toString).collect(Collectors.toList());
            String value =  mapper.writeValueAsString(types);
            ps.setString(i,value);
        } catch (Exception e) {
            throw new SQLException("Error converting Enum list to JSON", e);
        }
    }

    @Override
    public List<SpotType> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return readJson(rs.getString(columnName));
    }

    @Override
    public List<SpotType> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return readJson(rs.getString(columnIndex));
    }

    @Override
    public List<SpotType> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return readJson(cs.getString(columnIndex));
    }

    private List<SpotType> readJson(String json) {
        if (json == null || json.isEmpty()) {
            return Collections.emptyList();
        }
        try {
            return mapper.readValue(json, TYPE_REF);
        } catch (Exception e) {
            throw new RuntimeException("Error converting JSON to Enum list", e);
        }
    }
}